# -*- coding: utf_8 -*-
# @Create   : 2021/9/1 11:15
# @Author   : yh
# @Remark   : 巡检任务db层
import logging
import time
from typing import List

from mxsoftpy import DB
from mxsoftpy.exception import DBError, DataError, ParamsError

from model.common.VideoManage.VideoQuality.inspection_task import InspectionTaskResponseModel
from db.common.VideoManage.VideoQuality.conf import round_test_items


class InspectionTaskDB(DB):
    """
    巡检任务db类
    """

    def __task_name_duplicate_check(self, name: str, code: str = None):
        """
        巡检任务名称校验
        """
        self.tree.open('VideoQuality', 'InspectionTask', file='IOT')
        res_list = self.tree.filter(name=name, state=1)[1]
        if res_list and res_list[0] != code:
            raise ParamsError("%s任务名称已存在" % name)

    def create_or_update_items(self, plan_code: str, items: List[dict]) -> bool:
        """
        添加巡检计划内的检测项目
        :param plan_code: 巡检计划code
        :param items: 检测项目详情
            eg:
                [
                    {
                        "item_code": 1,
                        "confidence": 50
                    },
                    {
                        "item_code": 2,
                        "confidence": 30
                    }
                ]
        """
        # try:
        #     self.tree.open('VideoQuality', 'InspectionTask\\%s\\TestItems' % plan_code, file='IOT')
        #     self.tree.delete()
        # except DBError:
        #     pass
        # finally:
        self.tree.open('VideoQuality', 'InspectionTask\\%s\\TestItems' % plan_code, file='IOT', path_flag=True)
        for item in items:
            self.tree.insert_key_items([('test_code', item['test_code']), ('confidence', item['confidence'])])
        return True

    def create(self, **kwargs):
        """
        添加巡检任务
        :param kwargs: 要添加的属性及值
        """
        self.__task_name_duplicate_check(kwargs['name'])
        code = self.tree.insert_key_items([(k, v) for k, v in kwargs.items()])
        logging.info('新增了一个巡检任务，任务code：%s，任务内容如下：' % code)
        logging.info(str(kwargs))
        return code

    def select(self, **kwargs):
        """
        列表展示巡检任务
        :param kwargs: 查询条件及分页参数
        """
        from db.common.VideoManage.VideoQuality.inspection_plan import InspectionPlanDB
        tree = self.tree.open('VideoQuality', 'InspectionTask', file='IOT')
        total, keys = tree.filter(**kwargs)
        sub_items = self.tree.sub_items(key_list=keys,
                                        prop_list=['name', 'state', 'task_state', 'inspection_plan_code', 'begin_time',
                                                   'end_time', 'device_num', 'test_num', 'normal_num', 'fault_num',
                                                   'failed_num', 'principal']) if keys else dict()

        inspection_plan = InspectionPlanDB().simple_list()

        res = dict()
        res['data'] = list()
        for key in keys:  # 保持排序、以及添加字段

            sub_items[key]['begin_time'] = time.strftime("%Y-%m-%d %H:%M",
                                                         time.localtime(sub_items[key]['begin_time'])) if \
                                                            sub_items[key].get('begin_time') else ''
            sub_items[key]['end_time'] = time.strftime("%Y-%m-%d %H:%M",
                                                       time.localtime(sub_items[key]['end_time'])) if \
                                                          sub_items[key].get('end_time') else ''
            # 判断plan_name
            if sub_items[key]['inspection_plan_code'] == '0':
                plan_name = '临时任务'
            elif inspection_plan.get(sub_items[key]['inspection_plan_code']):
                plan_name = inspection_plan[sub_items[key]['inspection_plan_code']]['name']
            else:
                logging.error('查询巡检任务时无法获取对应的巡检计划，任务code: %s, 无法获取的计划code: %s'
                              % (key, sub_items[key]['inspection_plan_code']))
                plan_name = ''
            try:
                self.tree.open('VideoQuality', 'InspectionTask\\%s\\TestItems' % key, file='IOT')
            except DBError as e:
                logging.error('获取单个巡检任务详情时出错：打开code %s失败，错误详情：%s' % (key, str(e)))
                raise DataError('错误的巡检任务code：%s' % key)
            sub_items[key]['TestItems'] = round_test_items(self.tree.sub_items())
            sub_items[key].update({
                                    'task_code': key,
                                    'inspection_plan_name': plan_name,
                                   })
            sub_items[key] = InspectionTaskResponseModel(**sub_items[key]).dict()
            res['data'].append(sub_items[key])

        return total, res

    def retrieve(self, task_code: str) -> dict:
        """
        获取单个巡检任务详情
        :param task_code: 要获取的任务code
        """
        try:
            self.tree.open('VideoQuality', 'InspectionTask\\%s' % task_code, file='IOT')
        except DBError as e:
            logging.error('获取单个巡检任务详情时出错：打开code %s失败，错误详情：%s' % (task_code, str(e)))
            raise DataError('错误的巡检任务code：%s' % task_code)
        item_dict = self.tree.items()
        try:
            self.tree.open('VideoQuality', 'InspectionTask\\%s\\TestItems' % task_code, file='IOT')
        except DBError as e:
            logging.error('获取单个巡检任务详情时出错：打开code %s失败，错误详情：%s' % (task_code, str(e)))
            raise DataError('错误的巡检任务code：%s' % task_code)

        item_dict["TestItems"] = round_test_items(self.tree.sub_items())
        return item_dict

    def delete(self, task_code: str) -> str:
        """
        删除巡检任务
        :param task_code: 要删除的任务code
        """
        self.tree.open('VideoQuality', 'InspectionTask\\%s' % task_code, file='IOT').insert_items(
            [('state', 0), ('update_time', int(time.time()))])
        logging.info('删除了一个巡检任务, 任务code：%s' % task_code)
        return task_code

    def update(self, task_code: str, **kwargs) -> str:
        """
        更新巡检任务，用于任务执行后，更新检测数量、成功数量等
        :param task_code: 要更新的任务code
        :param kwargs: 需要更新的属性及值
        """
        return self.tree.open('VideoQuality', 'InspectionTask\\%s' % task_code, file='IOT').insert_items(kwargs)

    def simple_list(self, keys: list = None,is_all: bool = False, **kwargs) -> dict:
        """
        返回符合条件的在用巡检任务
        """
        self.tree.open('VideoQuality', 'InspectionTask', file='IOT')
        if not keys:
            if is_all:
                keys = self.tree.filter(**kwargs)[1]
            else:
                keys = self.tree.filter(state=1, **kwargs)[1]
        data_dict = self.tree.sub_items(key_list=keys) if keys else dict()
        res_dict = dict()
        for key in keys:  # 按照创建时间排序
            res_dict[key] = data_dict[key]
        return res_dict
